package com.tedu.api.list;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * 迭代器：打印集合元素【接口】
 * 集合提供自己一套输出集合元素的方法---迭代器【类似for，增强for】
 * 包位置：java.util
 * Iterator      接口
 * 该接口是集合接口，提供便利元素的相关操作：问取删
 *
 * iterator()方法   返回值Iterator
 * 作用：获取一个用于遍历当前集合迭代器的实现类实力
 *
 * 遍历规则：问取删（删不是必须操作）
 */
public class Collection_iterator {
    @Test
    public void testIterator(){
        //创建集合
        Collection c1=new ArrayList();
        c1.add("1");  c1.add("2");
        c1.add("3");  c1.add("4");
        c1.add("5");  c1.add("6");
        //iterator（）获取一个用于遍历当髂肌和迭代器的实现类示例
        Iterator it=c1.iterator();
        //理解：拿到集合所有元素，封装迭代器创建对象过程--理解迭代器实例
        //使用Iterator--获取集合的某个元素，规则：问取删
        //Iterator接口--hasNext() 获取某个元素
        //思考：如果是70个元素   ---循环while 次数不固定
        while(it.hasNext()){//1.问：集合是否有元素
            //迭代器集合：获取元素   |next()获取元素
            String str=(String)it.next();//2.取：获取集合元素
            System.out.println("迭代器"+str);
        }
        //迭代器是否改变集合的元素内容
        System.out.println(c1);
    }
    /**
     * 试一试
     * 普通for---遍历c1集合   集合size()
     * 语法：for(int i=0;i<c11.size();i++){}
     * 增强for---遍历c1集合    接受类型：Object
     * 语法：for(Object c:c1){}
     * Iterator迭代器--集合提供接口
     */
    @Test
    public void testCollection(){
        //创建集合
        Collection c1=new ArrayList();
        c1.add("1");  c1.add("2");
        c1.add("3");  c1.add("4");
        c1.add("5");  c1.add("6");
        //普通for 遍历集合
       // for(int i=0;i<c1.size();i++){
          //  System.out.println("普通for："+i);
       // }
       //增强for
        for(Object c:c1){
            System.out.println("增强for"+c);
        }
    }

    /**
     * remove() 删除  Iterator迭代器  增强for
     * 作用：删除获取到的元素数据，提醒：问 取next方法 删
     *
     */
    @Test
    public void testRemove() {
        Collection c = new ArrayList();
        c.add("1");
        c.add("2");
        c.add("3");
        c.add("4");
        //需求：通过迭代器删除
        Iterator it = c.iterator();
        while (it.hasNext()) {  //问：有无元素
            String str=(String)it.next();       //取
            //        c.remove("#");//Collection中存在remove()
            //删除一定是迭代器
            if("#".equals(str)){ //若拿到str元素
                it.remove();    //则删除元素
            }
        }
        System.out.println("迭代器删除" + c);
    }
    /**
     * 增强for---底层使用Iterator迭代器【问取删】
     * c.remove("#")是Collection的删除方法，并不是迭代器方法
     * 需求：删除集合中元素“#”
     *
     */
    @Test
    public void testFor(){
        Collection c=new ArrayList();
        c.add("1");  c.add("2");
        c.add("3");  c.add("4");
        for(Object o:c){ //类型  类型引用：集合引用
            if("#".equals(o)){
                c.remove(o);
            }
        }
        System.out.println("删除集合元素"+c);
    }

    /**
     * E  element   泛型    JDK1.5新特性
     *     结合集合出现，，约束集合的使用的类型【基本数据类型，引用类型，包装类】
     *     泛型的原型：Object，泛型是编译器认可的，JVM虚拟机并不认可
     *     使用泛型是告诉编译器应该把泛型当成Object类型执行，便于编译器检查
     *     类型以及自动造型操作！
     *
     *     泛型使用：
     *     Collection<类型：基本类型，引用类型，包装类>
     *     =new ArrayList<类型；基本类型，引用类型，包装类>();
     *
     *     JDK1.7泛型使用
     *     Collection<类型：基本类型，引用类型，包装类> c
     *     =new ArrayList<>();
     *
     *     泛型：自动推导   通配符：？ 表示任意类型
     *     Collection<类型:?> c
     *            =new ArrayList<>()
     *            优点：保证类型安全： 提高代码重用性和灵活性
     *                 限定集合
     */
    //@Test
    //public void testType1(){
        //针对泛型自动推导  通配符 ?
    //    Collection<?> c1=new ArrayList<>();
    //    c.add("null"); c.add("2");
    //    c.add("3"); c.add("4");
    //  }
    @Test
    public void testType(){
        Collection<String> c=new ArrayList<>();
        c.add("123"); c.add("123"); c.add("123");
        //遍历Iterator
        Iterator<String> it=c.iterator();
        while(it.hasNext()){
            String str=it.next();
            System.out.println(str);
        }
    }
}


//-----限定集合传入类型
class Fruit { //父类
    private String name;//成员变量

    public Fruit(String name) {
        this.name = name;
    }

    public String getName() { //方法
        return name;
    }
}

class Apple extends Fruit {//子类1

    public Apple() {
        super("苹果");  //调用父类有参数构造器，传入name名称
    }
}

class Orange extends Fruit {//子类2

    public Orange() {
        super("橘子"); //调用父类有参数构造器，传入name名称
    }
}
//测试类---泛型上届
class TestJob{
    //泛型上届 1.定义方法，制定泛型规则--集合中类型约定为Apple与Orange
    public static void printFruit(Collection<? extends Fruit> fruits){
        //2.增强for循环打印：集合中类型约定为Apple与Orange
        for(Fruit fruit:fruits) {
            //3.方法能进入：Apple或Orange ---- 打印名字
            System.out.println(fruit.getName());
        }
    }
    public static void main(String[] args) {
        Collection<Apple> apples=new ArrayList<>();
        apples.add(new Apple());
        Collection<Orange> oranges=new ArrayList<>();
        oranges.add(new Orange());
        printFruit(apples);
        printFruit(oranges);
        //假设：西瓜
        //Collection<String> strings=new ArrayList<>();
        //strings.add(new String());
        //printFruit(strings);


    }
}



